﻿// Copyright (c) 2012 - 2020 Jared Zheng <jaredz at outlook dot com>
// Buddha Framework is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
//          http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
//
// Create : 2012-12-01 version 0.1 Jared Zheng <jaredz at outlook dot com>
// Update : 2018-12-05 version 3.1.5 Jared Zheng <jaredz at outlook dot com>

#include "stdafx.h"
#include "resource.h"
#include "network.h"
#include "ServerLoader.h"
#include "GateDlg.h"

///////////////////////////////////////////////////////////////////////////////////////////////////////////
// CGateDlg
XBEGIN_DLG_ID_WND_EXCHANGE( CGateDlg )
XDLG_ID_WND( IDC_CONNECT_MASTER,  m_ConnectMaster )
XDLG_ID_WND( IDC_UDP_TO_AUTHOR,   m_UDPListenAuthor )
XDLG_ID_WND( IDC_TCP_EXTERNAL,    m_TCPExternal )
XDLG_ID_WND( IDC_UDP_EXTERNAL,    m_UDPExternal )
XDLG_ID_WND( IDC_GATE_INFO,       m_ServerInfo )
XDLG_ID_WND( IDD_GATE,            m_Gate )
XEND_DLG_ID_WND_EXCHANGE( CXDlg )

CGateDlg::CGateDlg(void)
: m_uGateOnline(0)
, m_uGateTotal(0)
, m_uGateLoad(0)
, m_uMasterId(0)
{
}

CGateDlg::~CGateDlg(void)
{
}

LRESULT CGateDlg::OnInitDialog(void)
{
    RECT rc;
    GetClientRect(&rc);
    rc.top += (DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_HEIGHT);
    rc.top += (DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_HEIGHT);
    rc.top += (DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_HEIGHT);

    m_Gate.MoveWindow(0, rc.top, rc.right, (rc.bottom - rc.top));
    //
    CStringFix strTemp;
    strTemp.Load(IDC_CONNECT_MASTER);
    m_ConnectMaster.SetWindowText(*strTemp);

    strTemp.Load(IDC_UDP_TO_AUTHOR);
    m_UDPListenAuthor.SetWindowText(*strTemp);

    strTemp.Load(IDC_TCP_EXTERNAL);
    m_TCPExternal.SetWindowText(*strTemp);

    strTemp.Load(IDC_UDP_EXTERNAL);
    m_UDPExternal.SetWindowText(*strTemp);
    //
    InitServerData(PAKT_GATE + PAKT_MAX);
    return TRUE;
}

LRESULT CGateDlg::OnSize(WPARAM, LPARAM lParam, BOOL&)
{
    RECT rc   = { 0 };
    rc.right  = (Long)LOWORD(lParam);
    rc.bottom = (Long)HIWORD(lParam);

    rc.top += (DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_HEIGHT);
    rc.top += (DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_HEIGHT);
    m_ServerInfo.MoveWindow(0, rc.top, rc.right, DLG_ITEM_HEIGHT);

    rc.top += (DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_HEIGHT);
    m_Gate.MoveWindow(0, rc.top, rc.right, (rc.bottom - rc.top));

    rc.right /=2;
    if (rc.right > DLG_ITEM_WIDTH)
    {
        m_ConnectMaster.MoveWindow(0, 0, (rc.right - DLG_ITEM_GRAP), (DLG_ITEM_GRAP + DLG_ITEM_HEIGHT));
        m_UDPListenAuthor.MoveWindow((rc.right + DLG_ITEM_GRAP), 0, (rc.right - DLG_ITEM_GRAP), (DLG_ITEM_GRAP + DLG_ITEM_HEIGHT));

        rc.top = (DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_GRAP + DLG_ITEM_HEIGHT);
        m_TCPExternal.MoveWindow(0, rc.top, (rc.right - DLG_ITEM_GRAP), (DLG_ITEM_GRAP + DLG_ITEM_HEIGHT));
        m_UDPExternal.MoveWindow((rc.right + DLG_ITEM_GRAP), rc.top, (rc.right - DLG_ITEM_GRAP), (DLG_ITEM_GRAP + DLG_ITEM_HEIGHT));
    }
    return 0;
}

void CGateDlg::OnLive(bool bStart)
{
    CStringFix strTemp;
    if (bStart)
    {
        CStrAddr strAddr;

        strTemp.Load(IDC_TCP_EXTERNAL);
        GServerLoaderInst->m_Config.GetServerAddr(CServerConfig::CFG_LOAD_GATE, CServerConfig::CFG_LOAD_NONE, strAddr);
        strTemp.AppendFormat(TF("[%s]:%d"), *strAddr.strIp, strAddr.usPort);
        m_TCPExternal.SetWindowText(*strTemp);

        strTemp.Load(IDC_UDP_EXTERNAL);
        strTemp.AppendFormat(TF("[%s]:%d"), *strAddr.strIp, strAddr.usPort);
        m_UDPExternal.SetWindowText(*strTemp);
    }
    else
    {
        strTemp.Load(IDC_CONNECT_MASTER);
        m_ConnectMaster.SetWindowText(*strTemp);

        strTemp.Load(IDC_UDP_TO_AUTHOR);
        m_UDPListenAuthor.SetWindowText(*strTemp);

        strTemp.Load(IDC_TCP_EXTERNAL);
        m_TCPExternal.SetWindowText(*strTemp);

        strTemp.Load(IDC_UDP_EXTERNAL);
        m_UDPExternal.SetWindowText(*strTemp);

        m_uGateOnline = 0;
        m_uGateTotal  = 0;
        m_uGateLoad   = 0;
        m_uMasterId   = 0;
    }
    m_ServerInfo.SetWindowText(TF(""));
}

void CGateDlg::OnLink(Int nServerIndex, uintptr_t utData)
{
    CStringFix strTemp;
    if (nServerIndex == PAKT_MASTER)
    {
        strTemp.Load(IDC_CONNECT_MASTER);

        CNetAddr* pAddr = (reinterpret_cast<CNetAddr*>(utData));

        CStrAddr strAddr;

        GServerLoaderInst->m_Config.GetServerAddr(CServerConfig::CFG_LOAD_MASTER, CServerConfig::CFG_LOAD_NONE, strAddr);
        strTemp.AppendFormat(TF("[%s]:%d"), *strAddr.strIp, strAddr.usPort);

        GServerLoaderInst->m_NetworkPtr->TranslateAddr(strAddr.strIp, strAddr.usPort, *pAddr, false);
        strTemp.AppendFormat(TF("([%s]:%d)"), *strAddr.strIp, strAddr.usPort);

        m_ConnectMaster.SetWindowText(*strTemp);
    }
    else if (nServerIndex == PAKT_GATE)
    {
        strTemp.Load(IDC_UDP_TO_AUTHOR);

        CNetAddr* pAddr = (reinterpret_cast<CNetAddr*>(utData));

        CStrAddr strAddr;
        GServerLoaderInst->m_NetworkPtr->TranslateAddr(strAddr.strIp, strAddr.usPort, *pAddr, false);
        strTemp.AppendFormat(TF("[%s]:%d"), *strAddr.strIp, strAddr.usPort);
        m_UDPListenAuthor.SetWindowText(*strTemp);
    }
    else if (nServerIndex == PAKT_SERVICE)
    {
        strTemp.Format(TF("%llX"), utData);

        LVFINDINFO find = {0};
        find.flags  = LVFI_PARAM;
        find.lParam = (LPARAM)(utData);
        Int nIndex = m_Gate.FindItem(&find);
        if (nIndex == -1)
        {
            nIndex = m_Gate.GetItemCount();
            nIndex = m_Gate.InsertItem(nIndex, *strTemp);
        }
        if (nIndex >= 0)
        {
            strTemp.Load(IDS_ROUTINE_ID_ONLINE);
            m_Gate.SetItemText(nIndex, 1, *strTemp);

            strTemp.Load(IDS_NONE_MARK);
            m_Gate.SetItemText(nIndex, 2, *strTemp);
            m_Gate.SetItemText(nIndex, 3, *strTemp);

            m_Gate.SetItemData(nIndex, (uintptr_t)utData);
        }
    }
}

void CGateDlg::OnUpdate(Int nCount, uintptr_t utData)
{
    CStringFix strTemp;

    LVFINDINFO find = {0};
    find.flags = LVFI_PARAM;

    PULLong pData = reinterpret_cast<PULLong>(utData);
    for (Int i = 0; i < nCount; ++i)
    {
        find.lParam = (LPARAM)(pData[0]);
        Int nIndex = m_Gate.FindItem(&find);
        if (nIndex > -1)
        {
            strTemp.ToString(pData[1]);
            m_Gate.SetItemText(nIndex, 2, *strTemp);

            strTemp.ToString(pData[2]);
            m_Gate.SetItemText(nIndex, 3, *strTemp);
        }
        pData += 3;
    }
}

void CGateDlg::OnSync(Int nServerIndex, uintptr_t utData)
{
    if (nServerIndex == PAKT_GATE)
    {
        PSERVER_STATUS pStatus = reinterpret_cast<PSERVER_STATUS>(utData);
        m_uGateTotal  = pStatus->uTotal;
        m_uGateOnline = pStatus->uOnline;
        m_uGateLoad   = pStatus->usLoad / DATAD_TOPERCENT;
    }
    else
    {
        assert(nServerIndex == PAKT_MASTER);
        m_uMasterId   = (UInt)utData;
    }
}

void CGateDlg::OnSync(Int, CStream&)
{
}

void CGateDlg::OnUnlink(Int nServerIndex, uintptr_t utData)
{
    CStringFix strTemp;
    if (nServerIndex == PAKT_MASTER)
    {
        strTemp.Load(IDC_CONNECT_MASTER);
        m_ConnectMaster.SetWindowText(*strTemp);
    }
    else if (nServerIndex == PAKT_AUTHOR)
    {
        strTemp.Load(IDC_UDP_TO_AUTHOR);
        m_UDPListenAuthor.SetWindowText(*strTemp);
    }
    else if (nServerIndex == PAKT_SERVICE)
    {
        if (utData > 0)
        {
            LVFINDINFO find = {0};
            find.flags = LVFI_PARAM;
            find.lParam = (LPARAM)(utData);
            Int nIndex = m_Gate.FindItem(&find);
            if (nIndex > -1)
            {
                strTemp.Load(IDS_ROUTINE_ID_OFFLINE);
                m_Gate.SetItemText(nIndex, 1, *strTemp);

                strTemp.Load(IDS_NONE_MARK);
                m_Gate.SetItemText(nIndex, 2, *strTemp);
                m_Gate.SetItemText(nIndex, 3, *strTemp);
            }
        }
        else
        {
            m_Gate.DeleteAllItems();
        }
    }
}

void CGateDlg::UpdateServerInfo(void)
{
    CStringFix strInfo;
    strInfo.Load(IDC_GATE_INFO);

    CStringFix strTemp;
    strTemp.Format(*strInfo, m_uGateOnline, m_uGateTotal, m_uGateLoad, m_uMasterId);
    m_ServerInfo.SetWindowText(*strTemp);
}

CXListView* CGateDlg::GetListView(Int nServerIndex)
{
    UNREFERENCED_PARAMETER(nServerIndex);
    assert(nServerIndex == (PAKT_GATE + PAKT_MAX));
    return &m_Gate;
}




